/*
 使用地图基础组件绘制三维板块
*/

<template>
  <div
    id="map"
    class="container"
  />
</template>
<script>
import 'maptalks/dist/maptalks.css'
import * as maptalks from 'maptalks'

const geoJson = require('@/static/xiamen.json')

export default {
  name: 'MapCustom',
  data () {
    return {
      // 地图引擎
      mapEngine: null,
      map: this,
      center: [118.13245430046891, 24.495713873147764],
      urlTemplate: 'https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png',
      subdomains: ['a', 'b', 'c', 'd'],
      attribution: null,
      // 倾斜度
      pitch: 60,
      // toolbar
      // 旋转
      whirl: null,
      // 放大/缩小
      zoom: 12,
      // 轴承
      bearing: 0,
      // 屏幕坐标
      containerPoint: { x: null, y: null },
      // 地图坐标
      coordinatePoint: { x: null, y: null },
      geoJson: geoJson,
      // 高度
      height: 400

    }
  },
  mounted () {
    const _t = this
    this.$nextTick(() => {
      _t.mapEngine = _t.initMap()

      // 锁定视角
      _t.lockView()

      // 创建工具栏
      _t.addToolbar()

      // 增加缩放工具
      _t.addZoomTool()

      // 画区域面
      _t.drawArea()

      // 增加事件，监听获取到鼠标点击的坐标
      _t.mapEngine.on('click', function (e) {
        _t.containerPoint = e.containerPoint
        _t.coordinatePoint = _t.mapEngine.containerPointToCoordinate(e.containerPoint)
        console.log('屏幕坐标：' + JSON.stringify(_t.containerPoint))
        console.log('地图坐标：' + JSON.stringify(_t.coordinatePoint))
      })
    })
  },

  methods: {

    /**
             * 初始化地图
             */
    initMap () {
      const _t = this
      return new maptalks.Map('map', {
        // 默认中心点点位
        center: _t.center,
        // 缩放层级
        zoom: _t.zoom,
        // 倾斜度
        pitch: _t.pitch,
        // 最小缩放层级
        minZoom: 1,
        // 最大缩放层级
        maxZoom: 18,
        baseLayer: new maptalks.TileLayer('base', {
          // 电子地图图层
          urlTemplate: _t.urlTemplate,
          subdomains: _t.subdomains,
          attribution: _t.attribution
        })
      })
    },

    /**
             * 限制地图区域
             */
    lockView () {
      const extent = this.mapEngine.getExtent()
      this.mapEngine.setMaxExtent(extent)
    },

    /**
             * 添加图层
             */
    addLayer () {
      return new maptalks.VectorLayer('v').addTo(this.mapEngine)
    },

    /**
             * 创建工具栏
             */
    addToolbar () {
      const _t = this
      const map = this.mapEngine
      new maptalks.control.Toolbar({
        items: [
          {
            item: '放大',
            click: () => {
              map.setZoom(_t.zoom += 1)
            }
          },
          {
            item: '缩小',
            click: () => {
              map.setZoom(_t.zoom -= 1)
            }
          },
          {
            item: '旋转',
            click: () => {
              map.setBearing(_t.bearing -= 50)
            }
          },
          {
            item: '重置',
            click: () => {
              _t.mapDataReset(map)
            }
          },
          {
            item: '锁定',
            click: (t) => {
              if (t.target.item === '锁定') {
                map.setOptions({
                  // 可拖动
                  draggable: false,
                  // 平移
                  dragPan: false,
                  // 旋转
                  dragRotate: false,
                  // 间距
                  dragPitch: false,
                  // 滚动缩放
                  scrollWheelZoom: false,
                  // 点击 缩放
                  touchZoom: false,
                  // 双击缩放
                  doubleClickZoom: false
                })
                t.target.item = '取消锁定'
              } else {
                map.setOptions({
                  // 可拖动
                  draggable: true,
                  // 平移
                  dragPan: true,
                  // 旋转
                  dragRotate: true,
                  // 间距
                  dragPitch: true,
                  // 滚动缩放
                  scrollWheelZoom: true,
                  // 点击 缩放
                  touchZoom: true,
                  // 双击缩放
                  doubleClickZoom: true
                })
                t.target.item = '锁定'
              }
            }
          }
        ]
      }).addTo(map)
    },

    /**
             * 增加缩放工具
             */
    addZoomTool () {
      new maptalks.control.Zoom({
        // 工具位置
        position: 'top-left',
        // 是否是以线段条方式展示
        slider: false,
        // 是否显示缩放级别文本框
        zoomLevel: true
      }).addTo(this.mapEngine)
    },

    /**
             * 地图数据重置
             */
    mapDataReset () {
      this.pitch = 50
      this.bearing = 0
      this.zoom = 14
      this.mapEngine.setPitch(this.pitch)
      this.mapEngine.setBearing(this.bearing)
      this.mapEngine.setZoom(this.zoom)
    },

    /**
             * 再图层上画面
             */
    drawArea () {
      const options = this.getOptions()

      const lowSymbol = {}
      const topSymbol = {}
      Object.assign(lowSymbol, options.symbol)
      Object.assign(topSymbol, options.symbol)

      const lowOptions = {
        zIndex: 9,
        symbol: lowSymbol,
        properties: {
          altitude: 0
        }
      }

      const topOptions = {
        zIndex: 11,
        symbol: topSymbol,
        properties: {
          altitude: 400
        }
      }

      const _t = this

      const layer = new maptalks.VectorLayer('vector')
      // 创建底面
      _t.drawAreaPlan(_t.geoJson, layer, lowOptions)
      // 高面
      const centerCoordinate = _t.drawAreaPlan(_t.geoJson, layer, topOptions, true)

      const lineOptions = {
        zIndex: 10,
        symbol: options.symbol,
        properties: {
          altitude: 400
        }
      }
      const lineCoordinate = []
      if (geoJson.type === 'FeatureCollection') {
        geoJson.features.forEach(c => {
          lineCoordinate.push(c.geometry.coordinates[0])
        })
      }
      lineCoordinate.forEach(l => {
        new maptalks.LineString(l[0], lineOptions).addTo(layer)
      })

      _t.drawMark(centerCoordinate, layer)
      layer.setOptions({
        // 启用高度绘制
        enableAltitude: true,
        altitudeProperty: 'altitude',
        // 绘制高度线
        drawAltitude: {
          // lineWidth: 1,
          // lineColor: '#000',
          // 高度面的填充色
          polygonFill: options.symbol.polygonFill,
          // 高度面的透明度
          polygonOpacity: options.symbol.polygonOpacity
        }
      })
      layer.addTo(_t.mapEngine)
    },

    /**
             * 根据geojson画区域面
             * @param geoJson geoJson数据
             * @param layer 需要话的图层
             */
    drawAreaPlan (geoJson, layer, options, isActions) {
      const geometry = maptalks.GeoJSON.toGeometry(geoJson)

      const centerCoordinates = []

      if (geometry) {
        geometry.forEach(g => {
          g.setSymbol(options.symbol)
          const gProperties = g.properties
          // 避免信息覆盖
          gProperties.altitude = options.properties.altitude
          g.setProperties(gProperties)
          // 设置图形层级
          g.setZIndex(options.zIndex)
          // 设置信息框
          g.setInfoWindow({
            title: g.properties.name,
            content: '<br style="color:#f00">中心点：' + g.properties.center + ' </br>行政区划：' + g.properties.adcode + ' </br>父级行政区划：' + g.properties.parent.adcode + '</div>'
          })
          g.setMenu({
            width: 160,
            custom: false,
            items: [
              { item: '菜单一', click: function () { alert('Query Clicked!'); return false } },
              '-',
              { item: '菜单二', click: function () { alert('Edit Clicked!') } },
              { item: '菜单三', click: function () { alert('About Clicked!') } }
            ]
          })
          // 鼠标交互事件监听
          g.on('mouseenter', function (e) {
            e.target.updateSymbol({
              polygonFill: '#ffaeb0'
            })
          }).on('mouseout', function (e) {
            e.target.updateSymbol({
              polygonFill: 'rgb(135,196,240)'
            })
          })

          if (isActions) {
            g.on('click', function (e) {
              e.target.openInfoWindow(e.coordinate)
            })
          }

          // 获取中心坐标
          centerCoordinates.push(g.properties)
        })
      }
      layer.addGeometry(geometry)

      return centerCoordinates
    },

    drawMark (centerPointList, layer) {
      if (!centerPointList) {
        console.log('无区域中心点数据')
        return
      }
      const info = { content: '', width: 150, minHeight: 100 }
      const result = []
      // 这里 d 的数据格式是数组，如：[-0.113049, 51.498568]
      centerPointList.forEach(d => {
        if (!d.info) {
          d.info = info
        }
        // 设有高度、高亮的mark
        const mark = new maptalks.Marker(d.center, {
          // 设置了这个属性，会替换默认的图标
          // symbol: {
          // markerFile: 'foo.png',
          // textName: d.name
          // },
          properties: {
            // 高度设置
            altitude: 400
          }
        }).addTo(layer)
        mark.setInfoWindow({
          title: d.name,
          content: '<div>' + d.adcode + '</div>',
          // autoPan: true,
          width: d.info.width,
          minHeight: d.info.minHeight
          // 'custom': false,
          // 点击打开和关闭
          // autoOpenOn: 'click',
          // autoCloseOn: 'click'
        })

        // 没有高度的mark
        // new maptalks.Marker(d).updateSymbol({
        //   markerOpacity: 0.5,
        //   markerFill: '#bbb'
        // }).addTo(layer)

        mark.setZIndex(1000)
        result.push(mark)
      })
      return result
    },

    getOptions () {
      return {
        zIndex: 10,
        symbol: {
          // 线色
          lineColor: '#ff87a4',
          // 线宽
          lineWidth: 1,
          // 填充色
          polygonFill: 'rgb(135,196,240)',
          // 不透明度
          polygonOpacity: 0.9
        },
        properties: {
          // 高度设置（不生效，需要设置图层的高度polygonOpacity属性）
          altitude: 400
        }
      }
    }
  }
}
</script>

<style scoped lang="scss">
  html, body {
    margin: 0px;
    height: 100%;
    width: 100%;
  }

  .container {
    width: 100%;
    height: 100%
  }
</style>
